package org.zn.mvcbase.mybatis.ddl;



import java.lang.reflect.Field;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.ibatis.type.JdbcType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zn.mvcbase.mybatis.ddl.column.ColumnDefault;

import com.google.common.collect.Lists;

import tk.mybatis.mapper.annotation.ColumnType;

public class TableEntityProvider {
	
	private Logger log=LoggerFactory.getLogger(TableEntityProvider.class);
	private SqlTypeMapping typeMapping; 
	
	
	public SqlTypeMapping getTypeMapping() {
		return typeMapping;
	}

	public void setTypeMapping(SqlTypeMapping typeMapping) {
		this.typeMapping = typeMapping;
	}

	public TableEntityProvider() {
		// TODO Auto-generated constructor stub
		typeMapping=new SqlTypeMapping("mysql");
		
	}
	
	public TableEntityProvider(String dialect) {
		// TODO Auto-generated constructor stub
		typeMapping=new SqlTypeMapping(dialect);
		
	}
	

	public TableEntity  provide(Class<?> clazz) {
		
		Table table= clazz.getAnnotation(Table.class);
		
		if(table==null) {
			return null;
		}
		
		TableEntity entity=new TableEntity();
		
		entity.setTableName(table.name());
		entity.setSchema(table.schema());
		
		Field[] fields=clazz.getDeclaredFields();
		
		List<TableEntity.Column> columns=Lists.newArrayList();
		
		
		for (Field field : fields) {
			
			log.debug("find field:{} , javaType:{}",field.getName(),field.getType().getName());
			/**
			@Id
		    @Column(name = "INDX",)
			@Transient
			**/
			
		
			
			
			
		 	if(field.getAnnotation(Transient.class)!=null) continue;
			
		 	TableEntity.Column col=new TableEntity.Column();
		 	
		 	Column annoColumn= field.getAnnotation(Column.class);
		 	
		 	ColumnDefault cdf= field.getAnnotation(ColumnDefault.class);
		 	ColumnType ctype=field.getAnnotation(ColumnType.class);
		 	
		 	

		 	if(cdf!=null) {	
		 		col.setDefaultValue(cdf.defaulValue());
		 	}

		 	
			if(field.getAnnotation(Id.class)!=null) {
		 		col.setPk(true);
		 		col.setNotnull(true);
		 		col.setLength("32");
		 	
		 	}
		 	
		 	if(annoColumn==null) {
		 		
		 		col.setName(field.getName());
		 		
		 		String type=null;
		 		
		 		if(col.isPk()) {
		 			 type=typeMapping.getSqlType(field.getType().getName(),32,0);
		 			 entity.addId(col.getName());
		 		}else {
		 			
		 			type=typeMapping.getSqlType(field.getType().getName());
		 			
		 		}
		 		
		 		col.setType(type);
		 		
		 	//	col.setType(typeMapping.getSqlType(field.getType().getName()));
		 		

		 	}else {
		 		
		 		col.setName(annoColumn.name());
		 		
		 		col.setNotnull(!annoColumn.nullable());
		 		
		 		String jtype=field.getType().getName();
		 		
		 		String type=null;
		 		
		 		if(col.isPk()) {
		 			
		 			type=typeMapping.getSqlType(jtype,32,annoColumn.precision());
		 			entity.addId(col.getName());
		 		}else {
		 			
		 			type=typeMapping.getSqlType(jtype,annoColumn.length(),annoColumn.precision());
		 			
		 		}
		 		
		 		col.setType(type);
		 		col.setComent(annoColumn.columnDefinition());	
		 		
		 		
		 	}
		 	
		 	if(ctype!=null) {	
		 		
		 		JdbcType jt=ctype.jdbcType();
		 		
		 		
		 		col.setType(typeMapping.getSqlType(jt.toString()));
		 		
		 		if(typeMapping.getDialect().equals("mysql")&&jt.equals(JdbcType.TIMESTAMP)) {
		 			
		 			col.setNotnull(false);
		 			
		 		}
		 		
		 		
		 	}
		 	

		 	columns.add(col);
		 	
		}
		entity.setColumns(columns);
		
		return entity;

	}
	
	public TableEntity  provide(String clazz) {
		TableEntity te=null;
		 try {
			Class<?> clz=Class.forName(clazz);
			te=provide(clz);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return te;
		
	}

}
